package com.simpd.activity;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.http.HttpException;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpResponseException;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import cn.pedant.SweetAlert.SweetAlertDialog;

import com.example.simpd.R;
import com.simpd.db_helper.DatabaseHelper;
import com.simpd.http_helper.CustomHttpClient;
import com.simpd.http_helper.DownloadingHtmlTask;
import com.simpd.model.AssetHelperTask;
import com.simpd.model.NotifikasiSKPD;
import com.simpd.model.SynchronizeConstant;
import com.simpd.my_list_view.CustomAdapter;
import com.simpd.my_list_view.RowItem;
import com.simpd.my_spinner.NoDefaultSpinner;

import android.app.ActionBar;
import android.app.ProgressDialog;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

public class SynchronizeActivity extends Activity{
	ImageButton btnSinkronisasi; 
	ListView list;
	RelativeLayout loadingBar;
	RelativeLayout userFilter;
	EditText editSearch;
	Button 	btnTutup;
	
	NoDefaultSpinner spinner;
	Switch switcher;
	
	CustomAdapter adapter;
	private String result;
	private String unip;
	private int[] idsNotifikasi;
	private String[] data;
	
	private ArrayList<NotifikasiSKPD> currentNotifs; 
	
	private int totalUpdateData = 0;
	private String errorMessage = "";
	
	public static boolean dataChange; 
	public static int locationChange;
	
	
	private static final String DEFAULT_URL = "http://sppd.gorontaloprov.go.id/simpd/site/synchronize";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.sinkronisasi_activity);
		
		ActionBar actionBar = getActionBar(); 
		actionBar.hide();
		
		btnSinkronisasi = (ImageButton) findViewById(R.id.sinkronisasi_btn_update);
		list 			= (ListView) findViewById(R.id.sinkronisasi_list);
		loadingBar 		= (RelativeLayout) findViewById(R.id.sinkronisasi_loading_bar);
		userFilter		= (RelativeLayout) findViewById(R.id.sinkronisasi_search_group);
		editSearch 		= (EditText) findViewById(R.id.sinkronisasi_edittext_search);
		btnTutup		= (Button) findViewById(R.id.sinkronisasi_btn_tutup);
		
		spinner			= (NoDefaultSpinner) findViewById(R.id.sinkronisasi_spinner);
		switcher 		= (Switch) findViewById(R.id.sinkronisasi_switch);
		
		setAssetFiles();
		
		data = new String[] {"semua notifikasi", "sudah dibaca", 
							 "belum dibaca", "tanggal terbaru", 
							 "tanggal terlama", "user filter", 
							 "filter skpd"};
					
		unip = getIntent().getExtras().getString("unip", "196206062012011001_default");
		ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(this, 
									       android.R.layout.simple_spinner_dropdown_item, 
									       data);
		
		currentNotifs = new ArrayList<NotifikasiSKPD>();
		
		spinner.setAdapter(adapterSpinner);
		setAdapterDefaultData();
		
		btnSinkronisasi.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// processSinkronisasi(v);
				Intent intent = new Intent(SynchronizeActivity.this, ExampleActivity.class);
				startActivity(intent);
				
			}
		});
		
		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				
				ArrayList<NotifikasiSKPD> arraylist = null;
				DatabaseHelper db = new DatabaseHelper(getApplicationContext());
				String message = "Semua Notifikasi";
				switch (position) {
				case SynchronizeConstant.DEFAULT_NOTIF :
					setAdapterDefaultData();
					message = "Semua Notifikasi";
					break;
				case SynchronizeConstant.HAS_READ : 
					adapter.filterHasRead(true);
					message = "Notifikasi yang sudah terbaca.";
					break;
				case SynchronizeConstant.NOT_READ : 
					adapter.filterHasRead(false); 
					message = "Notifikasi yang belum terbaca.";
					break;
				case SynchronizeConstant.NEWLY : 
					arraylist = db.getAllNotifikasi(DatabaseHelper.KEY_TANGGAL_UPDATE, false);
					updateAdapterListView(arraylist);
					message = "Notifikasi paling baru.";
					break;
				case SynchronizeConstant.OLD : 
					arraylist = db.getAllNotifikasi(DatabaseHelper.KEY_TANGGAL_UPDATE, true);
					updateAdapterListView(arraylist);
					message = "Notifikasi paling lama.";
					break;
				case SynchronizeConstant.USER_FILTER :
					spinner.setVisibility(View.GONE);
					userFilter.setVisibility(View.VISIBLE);
					message = "Notifikasi berdasarkan filter user.";
					break;
					
				case SynchronizeConstant.FILTER_SKPD :
					showPopupSkpd();
					message = "Filter notifikasi berdasarkan SKPD";
					break;

				default:
					message = "Notifikasi default.";
					break;
				}
				
				Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
				
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				// TODO Auto-generated method stub
				
			}
			
		});
		
		editSearch.addTextChangedListener(new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				String text = editSearch.getText().toString().toLowerCase(Locale.getDefault());
				adapter.filter(text);
				adapter.notifyDataSetChanged();
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				
			}
		});
		
		btnTutup.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				editSearch.setText("");
				userFilter.setVisibility(View.GONE);
				spinner.setSelection(SynchronizeConstant.DEFAULT_NOTIF);
				spinner.setVisibility(View.VISIBLE);
				
			}
		});
		
		switcher.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				if(isChecked){
					spinner.setVisibility(View.VISIBLE);
				}else{
					editSearch.setText("");
					spinner.setSelection(SynchronizeConstant.DEFAULT_NOTIF);
					spinner.setVisibility(View.GONE);
					userFilter.setVisibility(View.GONE);
					setAdapterDefaultData();
				}
			}
		});
		
	}
	
	private void setAssetFiles(){
		ProgressDialog progress = new ProgressDialog(SynchronizeActivity.this);
		progress.setTitle("Menyalin Assets"); 
		progress.setMessage("sedang menyalin assets...");
		progress.setCanceledOnTouchOutside(false);
		new AssetHelperTask(this, progress).execute();
	}
	
	/**
	 * type void 
	 * used to set data to show all default notifications
	 */
	private void setAdapterDefaultData(){
		DatabaseHelper db = new DatabaseHelper(this);
		ArrayList<NotifikasiSKPD> allNotifikasi = db.getAllNotifikasi(DatabaseHelper.KEY_TANGGAL_UPDATE, false);
		updateAdapterListView(allNotifikasi);
	}
	
	/**
	 * @param data
	 * used to update item of list view base on arraylist data
	 */
	private void updateAdapterListView(ArrayList<NotifikasiSKPD> data){
		// get data notifikasi from database
		List<RowItem> rowItems = new ArrayList<RowItem>();
		RowItem row = null;
		String tanggal = null;
		idsNotifikasi = new int[data.size()];
		int i = 0;
		int tempIcon = 0;
		for (NotifikasiSKPD notifikasi : data) {
			row = new RowItem();
			
			tempIcon = 0;
			if(notifikasi.getTipeSurat().equalsIgnoreCase("telaah")){
				tempIcon = notifikasi.getStatus() == 2 ? R.drawable.icon_tlh_signature : R.drawable.icon_tlh;
			}else{
				tempIcon = notifikasi.getStatus() == 2 ? R.drawable.icon_spt_signature : R.drawable.icon_spt;
			}
			
			row.setIconId(tempIcon);
			row.setTitle(notifikasi.getSkpd());
			row.setSubtitle(notifikasi.getPerihal());
			tanggal = notifikasi.getTanggalUpdate().substring(0, 10);
			tanggal = tanggal.replace("-", "/");
			row.setValue(tanggal);
			
			if(notifikasi.getStatus() == 0) 
				row.hasRead(false);
			else
				row.hasRead(true); 
			
			rowItems.add(row);
			Log.d("[notifikasi-id]", "id notifikasi : "+notifikasi.getId());
			idsNotifikasi[i] = notifikasi.getId();
			i++;
		}
		
		adapter = new CustomAdapter(this, rowItems);
		list.setAdapter(adapter);
	
		list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				
				DatabaseHelper db = new DatabaseHelper(getApplicationContext()); 
				NotifikasiSKPD notifikasi = db.getNotifikasi(idsNotifikasi[position]);
				Log.d("[notifikasi-row]", "get notifikasi dengan id : "+idsNotifikasi[position]);
				notifikasi.setStatus(1);
				db.update(idsNotifikasi[position], notifikasi);
				
				RowItem rowItem = (RowItem) adapter.getItem(position);
				rowItem.hasRead(true);
				adapter.setItem(position, rowItem);
				adapter.notifyDataSetChanged();
				
				Intent intent = new Intent(SynchronizeActivity.this, DetailNotifikasiActivity.class);
				intent.putExtra("unip", unip);
				intent.putExtra("url", notifikasi.getOnlineUrl());
				intent.putExtra("id", notifikasi.getId());
				intent.putExtra("position", position);
				startActivity(intent);
			}
		});
				
	}
	
	/**
	 * type void 
	 * digunakan untuk menampilkan pop up window yang berisi
	 * list skpd 
	 */
	public void showPopupSkpd(){
		LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
		View view = layoutInflater.inflate(R.layout.popup_window, null); 
		final PopupWindow popup = new PopupWindow(view, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT,true);
		
		popup.setAnimationStyle(R.style.popupAnimationUpDown);
		
		TextView title 		= (TextView) view.findViewById(R.id.popup_title); 
		ListView listPopup 	= (ListView) view.findViewById(R.id.popup_list);
		Button btnDismiss 	= (Button) view.findViewById(R.id.popup_button_dismiss);
		
		title.setText("Pilih jenis SKPD");
		title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
		title.setTextColor(Color.BLUE);
		
		btnDismiss.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				popup.dismiss();
			}
		});
		
		DatabaseHelper db = new DatabaseHelper(this);
		ArrayList<String> jenisSkpd = db.getDistinctSkpd();
		
		final List<RowItem> rowPopup = new ArrayList<RowItem>();
		RowItem item = null;
		for (String skpd : jenisSkpd) {
			item = new RowItem(); 
			item.setIconId(R.drawable.icon_stack); 
			item.setTitle(skpd); 
			item.setSubtitle("filter notifikasi dengan jenis skpd : "+skpd);
			item.setValue("");
			rowPopup.add(item);
		}
		
		CustomAdapter adapterPopup = new CustomAdapter(this, rowPopup);
		adapterPopup.setOffsetDefault(5);
		listPopup.setAdapter(adapterPopup);
		
		listPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				String selectedSkpd = rowPopup.get(position).getTitle();
				adapter.filterByTitle(selectedSkpd);
				popup.dismiss();
			}
		});
		
		View parentView = new View(getApplicationContext());
		BitmapDrawable drawable = new BitmapDrawable();
		popup.setBackgroundDrawable(drawable);
		popup.showAtLocation(parentView, Gravity.CENTER, 0, 0);
		
	}
	
	
	/**
	 * @param v
	 * method ini dijalankan ketika tombol sinkronisasi di klik.
	 * process di dalam method: 
	 *    1. inisialisasi parameter untuk httpClient
	 *    2. inisialisasi url untuk httpClient
	 *    3. menjalankan Thread SinkronisasiThread untuk melakukan sinkronisasi
	 */
	private void processSinkronisasi(View v){
		String url = DEFAULT_URL;
		DatabaseHelper db 	= new DatabaseHelper(getApplicationContext());
		
		NotifikasiSKPD notifikasi = db.getLastNotifikasi(); 
		String lastUpdated = "";
		if(notifikasi !=null){
			lastUpdated = notifikasi.getTanggalUpdate(); 
		}
		
		ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>(); 
		postParameters.add(new BasicNameValuePair("unip", unip)); 
		postParameters.add(new BasicNameValuePair("fulltok", "123")); 
		postParameters.add(new BasicNameValuePair("last_updated", lastUpdated));
		
		Thread thread = new Thread(new SinkronisasiThread(url, postParameters));
		thread.start();
	}
	
	/**
	 * 
	 * @param url
	 * @param postParameters
	 * @return true if success, false otherwise
	 */
	private boolean sinkronisasiUseThreads(String url, ArrayList<NameValuePair> postParameters){
		boolean successful = false;
		
		String response = null;
		result 	= null;
		
		Log.d("[url]", "url : "+url);
		Log.d("[post-params]", "unip : "+postParameters.get(0).getValue()+"" +
							   "fulltok : "+postParameters.get(1).getValue()+"" +
							   "last_updated : "+postParameters.get(2).getValue());
		
		try {
			response = CustomHttpClient.executeHttpPost(url, postParameters);
			Log.d("[post-request]", "perform post request");
			
			result = response.toString();
			
			
//			result = result.replaceAll("\\s+", "");
			Log.d("[request-result]", "result : "+result);
			JSONArray jArray = new JSONArray(result);			
			DatabaseHelper db = new DatabaseHelper(this);
			NotifikasiSKPD notifikasi;
			long inserted_id = 0;
			totalUpdateData  = 0;
			String tempUrl 	 = null;
			currentNotifs.clear();
			for (int i = 0; i < jArray.length(); i++) {
				JSONObject jsonData = jArray.getJSONObject(i);
				notifikasi = new NotifikasiSKPD();
				notifikasi.setSkpd(jsonData.getString("skpd").toString());
				notifikasi.setTanggalUpdate(jsonData.getString("tanggal_berubah_status").toString()); 
				notifikasi.setPerihal(jsonData.getString("perihal").toString()); 
				notifikasi.setTipeSurat(jsonData.getString("tipe_surat").toString());
				tempUrl = jsonData.getString("url").toString();
				Log.d("[url-from json]", "url : "+tempUrl);
				tempUrl = tempUrl.replaceAll("\\\\", "");
				Log.d("[inserted-url]", "url : "+tempUrl);
				notifikasi.setOnlineUrl(tempUrl);
				
				inserted_id = db.insertNotifikasi(notifikasi);
				if(inserted_id !=0){
					Log.d("[inserting-data]", "insert skpd "+notifikasi.getSkpd()+" successfully!");
				}else{
					Log.e("[inserting-failed]", "insert skpd : "+notifikasi.getSkpd()+" failed!!");
				}
				notifikasi.setId((int) inserted_id); 
				currentNotifs.add(notifikasi);
				inserted_id = 0;
				
			}
			totalUpdateData = jArray.length();
		} catch (HttpResponseException e) {
			Log.e("[error-httpResponse]", e.getMessage());
			errorMessage = e.getMessage();
		} catch (HttpException e) {
			Log.e("[error-http]", e.getMessage());
			errorMessage = e.getMessage();
		}catch (Exception e) {
			Log.e("[error-exception]", e.getMessage());
			errorMessage = e.getMessage();
		}finally{
			SynchronizeActivity.this.runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					setAdapterDefaultData();
					if(result !=null){
						/*ProgressDialog dialog = new ProgressDialog(SynchronizeActivity.this); 
						dialog.setTitle("Downloading HTML File");
						dialog.setTitle("downloading....");
						ArrayList<NameValuePair> parameters = new ArrayList<NameValuePair>();
						parameters.add(new BasicNameValuePair("unip", unip));
						new DownloadingHtmlTask(dialog, currentNotifs, parameters).execute();*/
						
						SweetAlertDialog alert = new SweetAlertDialog(SynchronizeActivity.this, 
																	  SweetAlertDialog.SUCCESS_TYPE);
						
						alert.setTitleText("Update data berhasil !");
						String message = "";
						if(totalUpdateData > 0){
							message = totalUpdateData+" data baru berhasil ditambahkan!";
						}else{
							message = "Belum terdapat data baru!";
						}
						
						alert.setContentText(message);
						alert.show();
						
					}else{
						SweetAlertDialog alert = new SweetAlertDialog(SynchronizeActivity.this, 
													SweetAlertDialog.ERROR_TYPE);
						alert.setTitleText("Sinkronisasi gagal!");
						alert.setContentText("Terjadi kesalahan karena : "+errorMessage);
						alert.show();
					}
					loadingBar.setVisibility(View.GONE);
				}
			});
		}
		
		 
		return successful;
	}
	
	
	/**
	 * 
	 * InnerClass SinkronisasiThread 
	 * digunakan untuk menjalankan sinkronisasi 
	 * di Thread yang terpisah dari UIMainThread
	 * 
	 */
	
	private class SinkronisasiThread implements Runnable{
		private ArrayList<NameValuePair> postParameters; 
		private String url;
		
		/**
		 * @param url : alamat url untuk melakukan process httpClient
		 * @param postParameters : parameter untuk httpPost
		 */
		public SinkronisasiThread(String url, ArrayList<NameValuePair> postParameters){
			this.url 			= url;
			this.postParameters = postParameters;
		}
		
		@Override
		public void run() {
			SynchronizeActivity.this.runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					loadingBar.setVisibility(View.VISIBLE);
				}
			});
			sinkronisasiUseThreads(url, postParameters);			
		}
		
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		if(dataChange==true){
			RowItem item = (RowItem) adapter.getItem(locationChange);
			int updateIcon = item.getIconId() == R.drawable.icon_spt || item.getIconId() == R.drawable.icon_spt_signature ? 
					R.drawable.icon_spt_signature : R.drawable.icon_tlh_signature;
			item.setIconId(updateIcon);
			adapter.setItem(locationChange, item);
			adapter.notifyDataSetChanged();
			list.invalidate();
			Log.d("[onResume]", "update adapter with position : "+locationChange);
			dataChange  	= false;
			locationChange  = 1000;
		}
	}
	
	public static void onDatasetChange(boolean isChange, int location){
		dataChange 	= isChange; 
		locationChange = location;
	}
}
